package com.dingwen.treasure.business.service.impl;

import com.dingwen.treasure.business.service.CompletableFutureService;
import com.dingwen.treasure.model.entity.mybatisplus.SysConfig;
import com.dingwen.treasure.mybatisplus.service.SysConfigService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;

/**
 * 　CompletableFutureServiceImpl: TODO 自定义线程池卡死
 * 　@author dingwen
 * 　@date 2022/8/3
 */
@Service
@Slf4j
public class CompletableFutureServiceImpl implements CompletableFutureService {

    /**
     * 系统配置服务
     */
    @Resource
    private SysConfigService sysConfigService;


    /**
     * 事务管理
     */
    @Resource
    private TransactionTemplate transactionTemplate;

    /**
     * 测试事务控制
     */
    @Override
    @SneakyThrows(Throwable.class)
    public void testAcid() {
        AtomicBoolean atomicBoolean = new AtomicBoolean(false);
        CountDownLatch mainCountDownLatch = new CountDownLatch(1);
        CountDownLatch businessCountDownLatch = new CountDownLatch(2);

        // step1 执行业务进行新增
        //CompletableFuture.runAsync(() -> {
        new Thread(() ->
                test(unused -> {
                    SysConfig sysConfig = SysConfig.builder().name("step1新增配置").build();
                    sysConfigService.save(sysConfig);
                    log.info("当前执行线程：{}", Thread.currentThread().getName());
                },atomicBoolean,mainCountDownLatch,businessCountDownLatch)
        ).start();

        //}, asyncExecutor).thenRunAsync(() -> {
        new Thread(() ->
                test(unused -> {
                    SysConfig sysConfig = SysConfig.builder().name("step2新增配置").build();
                    sysConfigService.save(sysConfig);
                    log.info("当前执行线程：{}", Thread.currentThread().getName());
                    int i = 10 / 0;
                },atomicBoolean,mainCountDownLatch,businessCountDownLatch)
        ).start();


        //}, asyncExecutor).exceptionally(ex -> {
        //    ex.printStackTrace();
        //    return null;
        //});

         //step2 其他业务抛出异常
        log.info("当前执行线程：{}", Thread.currentThread().getName());

        businessCountDownLatch.await();
        mainCountDownLatch.countDown();
        log.info("finished...");


    }

    @SneakyThrows({Throwable.class})
    public void test(Consumer<Void> consumer, AtomicBoolean atomicBoolean, CountDownLatch mainCountDownLatch, CountDownLatch businessCountDownLatch) {
        DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
        // 事务传播特性
        defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        PlatformTransactionManager transactionManager = transactionTemplate.getTransactionManager();
        TransactionStatus transactionStatus = transactionManager.getTransaction(defaultTransactionDefinition);

        try {
            consumer.accept(null);
        } catch (Exception e) {
            atomicBoolean.set(true);
            e.printStackTrace();
            log.info("test");
        }finally {
            businessCountDownLatch.countDown();
            mainCountDownLatch.await();
            if (atomicBoolean.get()) {
                transactionManager.rollback(transactionStatus);
            } else {
                transactionManager.commit(transactionStatus);
            }
        }
    }


}
